package com.glsc.ngateway.platform.vo.converter;

import com.glsc.ngateway.common.api.oaflow.dto.VITSystemOAFlowStatisticsDto;
import com.glsc.ngateway.common.api.oaflow.dto.oaflow.SystemFlowStatisticsDto;
import com.glsc.ngateway.platform.vo.SystemFlowStatisticsVo;
import com.google.common.collect.ImmutableMap;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhengyr
 * @date 2023/8/29-17:34
 * 系统关联流程统计数据 dto到vo转换器
 */
public class SystemFlowStatisticsConverter {
    final static Map<Integer,String> changeLevelMap = ImmutableMap.of(0,"一级变更",1,"二级变更",2,"三级变更",3,"四级变更");
    final static Integer TOP_AMOUNT = 10;
    final static Integer BAR_TOP_AMOUNT = 5;
    final static String OTHER="其他";
    /**
     *
     * @param dto
     * @param systemDictMap
     * @param systemCount
     * @return
     */
    public static SystemFlowStatisticsVo dto2vo(SystemFlowStatisticsDto dto, Map<String, String> systemDictMap, Integer systemCount){

        SystemFlowStatisticsVo.SystemFlowStatisticsVoBuilder voBuilder = SystemFlowStatisticsVo.builder();
        //流程分组柱状图
        SystemFlowStatisticsVo.MonthBarFlowTypeData monthBarFlowTypeData = getMonthBarFlowTypeData(dto);
        //流程分组饼图 大于10个取的和小于10的情况取不同的结果集
        List<SystemFlowStatisticsVo.Pie> flowTypePieData;
        if(dto.getCountFlowTypeList().size() > TOP_AMOUNT){
            flowTypePieData = dto.getCount10FlowTypeList().stream().map(h ->
                    SystemFlowStatisticsVo.Pie.builder().name(h.getWorkflowName()).value(h.getCount()).build()).collect(Collectors.toList());
        }else{
            flowTypePieData = dto.getCountFlowTypeList().stream().map(h ->
                    SystemFlowStatisticsVo.Pie.builder().name(h.getWorkflowName()).value(h.getCount()).build()).collect(Collectors.toList());
        }

        List<SystemFlowStatisticsVo.Pie> systemModifyAuditFlowPieData = dto.getSystemChangeFlowCountList().stream().map(h ->
                SystemFlowStatisticsVo.Pie.builder().name(changeLevelMap.getOrDefault(h.getChangeLevel(),"暂无级别")).value(h.getCount()).build()).collect(Collectors.toList());

        List<SystemFlowStatisticsVo.Pie> testSystemModifyFlowPieData = dto.getSystemChangeTestFlowCountList().stream().map(h ->
                SystemFlowStatisticsVo.Pie.builder().name(changeLevelMap.getOrDefault(h.getChangeLevel(),"暂无级别")).value(h.getCount()).build()).collect(Collectors.toList());

        if(systemCount > 1){
            //只有多个系统时需要请求的数据
            SystemFlowStatisticsVo.MonthBarSystemTypeData monthBarSystemTypeData = getMonthBarSystemTypeData(dto, systemDictMap);
            //系统分组饼图 大于10个取的和小于10的情况取不同的结果集
            List<SystemFlowStatisticsVo.SystemTypePie> systemTypePieData;
            if(dto.getCountSystemTypeList().size() > TOP_AMOUNT){
                systemTypePieData = dto.getCount10SystemTypeList().stream().map(h ->
                        SystemFlowStatisticsVo.SystemTypePie.builder().systemClassNo(h.getSystemClassNo())
                                .name(OTHER.equals(h.getSystemClassNo()) ? OTHER : systemDictMap.get(h.getSystemClassNo()))
                                .value(h.getCount()).build()).collect(Collectors.toList());
            }else{
                systemTypePieData = dto.getCountSystemTypeList().stream().map(h ->
                        SystemFlowStatisticsVo.SystemTypePie.builder().systemClassNo(h.getSystemClassNo())
                                .name(systemDictMap.get(h.getSystemClassNo()))
                                .value(h.getCount()).build()).collect(Collectors.toList());
            }

            List<SystemFlowStatisticsVo.TimelineMultiple> timelineMultipleData = getTimelineMultipleData(dto);
            voBuilder.monthBarSystemTypeData(monthBarSystemTypeData).systemTypePieData(systemTypePieData).timelineMultipleData(timelineMultipleData);
        }else{
            //只有单个系统时需要请求的数据
            //先按发起日期分组
            Map<String, List<VITSystemOAFlowStatisticsDto>> groupMap = dto.getChangeFlowLineSingleList().stream().collect(Collectors.groupingBy(
                    h -> h.getApplyDate(),
                    LinkedHashMap::new,
                    Collectors.toList()
            ));
            List<SystemFlowStatisticsVo.Timeline> timelineData = groupMap.entrySet().stream().map(h -> SystemFlowStatisticsVo.Timeline.builder().label(h.getKey()).children(
                    h.getValue().stream().map(o -> SystemFlowStatisticsVo.TimelineChild.builder()
                            .level(o.getChangeLevel())
                            .flowCreateOperatorName(o.getUserName())
                            .processCreateTime(o.getApplyDate())
                            .processDefineKeyName(o.getWorkflowName())
                            .processTitle(o.getRequestName())
                            .processId(o.getRequestId())
                            .build()).collect(Collectors.toList())
            ).build()).collect(Collectors.toList());
//            List<SystemFlowStatisticsVo.Timeline> timelineData = dto.getChangeFlowLineSingleList().stream().map(h ->
//                    SystemFlowStatisticsVo.Timeline.builder().label(h.getApplyDate()).children(
//                    SystemFlowStatisticsVo.TimelineChild.builder()
//                            .level(h.getChangeLevel())
//                            .flowCreateOperatorName(h.getUserName())
//                            .processCreateTime(h.getApplyDate())
//                            .processDefineKeyName(h.getWorkflowName())
//                            .processTitle(h.getRequestName())
//                            .build()
//            ).build()).collect(Collectors.toList());
            voBuilder.timelineData(timelineData);
        }

        voBuilder.monthBarFlowTypeData(monthBarFlowTypeData)
                .flowTypePieData(flowTypePieData)
                .systemModifyAuditFlowPieData(systemModifyAuditFlowPieData)
                .testSystemModifyFlowPieData(testSystemModifyFlowPieData);

        return voBuilder.build();
    }

    public static SystemFlowStatisticsVo.MonthBarFlowTypeData getMonthBarFlowTypeData(SystemFlowStatisticsDto dto){
        List<String> yearMonthList = new ArrayList<>();
        LinkedHashMap<String, SystemFlowStatisticsVo.Series> workflowNameMap = new LinkedHashMap<>();
        //数据源是总数排前10个的流程列表，柱状图要求是取前5个
        List<VITSystemOAFlowStatisticsDto> count5FlowTypeList = dto.getCount10FlowTypeList().size() > BAR_TOP_AMOUNT?
                dto.getCount10FlowTypeList().subList(0,BAR_TOP_AMOUNT): dto.getCount10FlowTypeList();
        //前5大流程名称数组
        List<String> workflowName5List = count5FlowTypeList.stream().map(h -> h.getWorkflowName()).collect(Collectors.toList());

        //记录每个月下所有流程总数（type==line的Seires
        LinkedHashMap<String,Integer> sumMap = new LinkedHashMap<>();
        //处理原始数据集，不在前5条里的，合并为其他类，计算总数
        LinkedHashMap<String, Map<String,Integer>> tempMap = new LinkedHashMap<>();

        for (VITSystemOAFlowStatisticsDto h : dto.getCountFlowTypeMonthList()) {
            sumMap.put(h.getYearmonth(), sumMap.get(h.getYearmonth())!=null? sumMap.get(h.getYearmonth())+ h.getCount():h.getCount());
            Map<String, Integer> childMap = tempMap.getOrDefault(h.getYearmonth(), new HashMap<>());
            if(workflowName5List.contains(h.getWorkflowName())){
                childMap.put(h.getWorkflowName(),h.getCount());
            }else{
                Integer otherCount = childMap.getOrDefault(OTHER, 0);
                otherCount+=h.getCount();
                childMap.put(OTHER ,otherCount);
            }
            tempMap.put(h.getYearmonth(),childMap);
        }
        //收集workflowNameMap
        int size = sumMap.entrySet().size();
        for (Map.Entry<String, Map<String, Integer>> yearMonthEntry : tempMap.entrySet()) {
            //通过月份，用来记录当前series-data插入索引
            if(!yearMonthList.contains(yearMonthEntry.getKey())){
                yearMonthList.add(yearMonthEntry.getKey());
            }
            Integer index = yearMonthList.size()-1 ;
            for (Map.Entry<String, Integer> childEntry : yearMonthEntry.getValue().entrySet()) {
                SystemFlowStatisticsVo.Series targetSeries = workflowNameMap.getOrDefault(childEntry.getKey(),
                SystemFlowStatisticsVo.Series.builder().type("bar").name(childEntry.getKey()).data(new Integer[size]).build());
                //在series-data的当前索引位置插入count值
                targetSeries.getData()[index] = childEntry.getValue();
                workflowNameMap.put(childEntry.getKey(), targetSeries);
            }
        }


        //收集workflowNameMap
//        int size = sumMap.entrySet().size();
//        for (VITSystemOAFlowStatisticsDto h : dto.getCountFlowTypeMonthList()) {
//            //通过月份，用来记录当前series-data插入索引
//            if(!yearMonthList.contains(h.getYearmonth())){
//                yearMonthList.add(h.getYearmonth());
//            }
//            Integer index = yearMonthList.size()-1 ;
//
//            SystemFlowStatisticsVo.Series targetSeries = workflowNameMap.getOrDefault(h.getWorkflowName(),
//                    SystemFlowStatisticsVo.Series.builder().type("bar").name(h.getWorkflowName()).data(new Integer[size]).build());
//            //在series-data的当前索引位置插入count值
//            targetSeries.getData()[index] = h.getCount();
//            workflowNameMap.put(h.getWorkflowName(),targetSeries);
//        }

        List<SystemFlowStatisticsVo.Series> seriesData = new ArrayList<>(workflowNameMap.values());
        seriesData.add(SystemFlowStatisticsVo.Series.builder().type("line").name("").data(new ArrayList<>(sumMap.values()).toArray(new Integer[size])).build());

        return SystemFlowStatisticsVo.MonthBarFlowTypeData.builder().seriesData(seriesData).xData(yearMonthList).build();
    }

    public static SystemFlowStatisticsVo.MonthBarSystemTypeData getMonthBarSystemTypeData(SystemFlowStatisticsDto dto, Map<String, String> systemDictMap){
        List<String> yearMonthList = new ArrayList<>();
        LinkedHashMap<String, SystemFlowStatisticsVo.Series> systemMap = new LinkedHashMap<>();
        //数据源是总数排前10个的系统列表，柱状图要求是取前5个
        List<VITSystemOAFlowStatisticsDto> count5SystemTypeList = dto.getCount10SystemTypeList().size() > BAR_TOP_AMOUNT?
                dto.getCount10SystemTypeList().subList(0,BAR_TOP_AMOUNT): dto.getCount10SystemTypeList();
        //前5大系统编号数组
        List<String> systemClassNo5List = count5SystemTypeList.stream().map(h -> h.getSystemClassNo()).collect(Collectors.toList());

        //记录每个月下所有流程总数的数组（type==line的Seires）
        LinkedHashMap<String,Integer> sumMap = new LinkedHashMap<>();

        //处理原始数据集，不在前5条里的，合并为其他类，计算总数
        LinkedHashMap<String, Map<String,Integer>> tempMap = new LinkedHashMap<>();

        for (VITSystemOAFlowStatisticsDto h : dto.getCountSystemTypeMonthList()) {
            sumMap.put(h.getYearmonth(), sumMap.get(h.getYearmonth())!=null? sumMap.get(h.getYearmonth())+ h.getCount():h.getCount());
            Map<String, Integer> childMap = tempMap.getOrDefault(h.getYearmonth(), new HashMap<>());
            if(systemClassNo5List.contains(h.getSystemClassNo())){
                childMap.put(h.getSystemClassNo(),h.getCount());
            }else{
                Integer otherCount = childMap.getOrDefault(OTHER, 0);
                otherCount+=h.getCount();
                childMap.put(OTHER,otherCount);
            }
            tempMap.put(h.getYearmonth(),childMap);
        }
        //收集systemMap
        int size = sumMap.entrySet().size();
        for (Map.Entry<String, Map<String, Integer>> yearMonthEntry : tempMap.entrySet()) {
            //通过月份，用来记录当前series-data插入索引
            if(!yearMonthList.contains(yearMonthEntry.getKey())){
                yearMonthList.add(yearMonthEntry.getKey());
            }
            Integer index = yearMonthList.size()-1 ;
            for (Map.Entry<String, Integer> childEntry : yearMonthEntry.getValue().entrySet()) {
                SystemFlowStatisticsVo.Series targetSeries = systemMap.getOrDefault(childEntry.getKey(),
                        SystemFlowStatisticsVo.Series.builder().type("bar")
                                .id(childEntry.getKey())
                                    .name(
                                            OTHER.equals(childEntry.getKey())? OTHER : systemDictMap.get(childEntry.getKey())
                                    ).data(new Integer[size]).build());
                //在series-data的当前索引位置插入count值
                targetSeries.getData()[index] = childEntry.getValue();
                systemMap.put(childEntry.getKey(), targetSeries);
            }
        }
        //收集Map
//        for (VITSystemOAFlowStatisticsDto h : dto.getCountSystemTypeMonthList()) {
//            sumMap.put(h.getYearmonth(), sumMap.get(h.getYearmonth())!=null? sumMap.get(h.getYearmonth())+ h.getCount():h.getCount());
//        }
//        int size = sumMap.entrySet().size();
//        dto.getCountSystemTypeMonthList().stream().forEach(h -> {
//            //通过月份，用来记录当前series-data插入索引
//            if(!yearMonthList.contains(h.getYearmonth())){
//                yearMonthList.add(h.getYearmonth());
//            }
//            Integer index = yearMonthList.size()-1 ;
//            SystemFlowStatisticsVo.Series targetSeries = systemMap.getOrDefault(
//                    systemClassNo5List.contains( h.getSystemClassNo())?h.getSystemClassNo():"other",
//                    SystemFlowStatisticsVo.Series.builder().type("bar").id(
//                            systemClassNo5List.contains( h.getSystemClassNo())?h.getSystemClassNo():"other"
//                    ).name(
//                            systemClassNo5List.contains( h.getSystemClassNo())?
//                                    systemDictMap.get(h.getSystemClassNo()): "其他"
//                    ).data(new Integer[size]).build());
//            //在series-data的当前索引位置插入count值
//            targetSeries.getData()[index] = h.getCount();
//            systemMap.put(h.getSystemClassNo(),targetSeries);
//
//        });

        List<SystemFlowStatisticsVo.Series> seriesData = new ArrayList<>(systemMap.values());
        seriesData.add(SystemFlowStatisticsVo.Series.builder().type("line").name("").data(new ArrayList<>(sumMap.values()).toArray(new Integer[size])).build());

        return SystemFlowStatisticsVo.MonthBarSystemTypeData.builder().seriesData(seriesData).xData(yearMonthList).build();
    }

    public static List<SystemFlowStatisticsVo.TimelineMultiple>  getTimelineMultipleData(SystemFlowStatisticsDto dto){
        LinkedHashMap<String, List<SystemFlowStatisticsVo.TimelineMutipleChild>> yearmonthMap = new LinkedHashMap<>();
        dto.getChangeFlowLineMultipleList().forEach(h->{
            List<SystemFlowStatisticsVo.TimelineMutipleChild> childList = yearmonthMap.getOrDefault(h.getYearmonth(), new ArrayList<>());
            childList.add(SystemFlowStatisticsVo.TimelineMutipleChild.builder().level(h.getChangeLevel()).count(h.getCount()).build());
            yearmonthMap.put(h.getYearmonth(), childList);
        });
        return yearmonthMap.entrySet().stream().map(h ->
                SystemFlowStatisticsVo.TimelineMultiple.builder().label(h.getKey()).children(h.getValue()).build()).collect(Collectors.toList());
    }
}
